
#include "ooc.h"



OOC_CLASS_META(CP_MC_PKG, CP_MC_TYPE, CP_SC_PKG, CP_SC_TYPE);

static CP_MC_FNAME* CPortion_default_init(CP_MC_FNAME* cthis);
static void Cportion_finalize(CP_MC_FNAME* cthis);
static void finalize(CP_MC_FNAME* cthis);



CP_MC_FNAME* OOC_CTOR_NAME(CP_MC_FNAME)(void) {

    OOC_PUB_BLOCK_TNAME(CP_MC_FNAME)* pPubBlock = MNULL;
    OOC_CLASS_PRO_TNAME(CP_MC_FNAME)* pProtected = MNULL;
#ifdef OOC_CFG_CLASS_PORTION_USE_PRIVATE
    OOC_CLASS_PRI_TNAME(CPORTION_MCNAME)* pPrivate = MNULL;
#endif
    
    
    CP_SC_FNAME* super = OOC_CTOR_NAME(CP_SC_FNAME)();

    if (MNULL == super)
        return MNULL;

    pPubBlock = OOC_MALLOC(sizeof (OOC_PUB_BLOCK_TNAME(CP_MC_FNAME)));
    if (MNULL == pPubBlock)
        goto error;

    pProtected = OOC_MALLOC(sizeof (OOC_CLASS_PRO_TNAME(CP_MC_FNAME)));
    if (MNULL == pProtected)
        goto error;

#ifdef OOC_CFG_CLASS_PORTION_USE_PRIVATE
    pPrivate = OOC_MALLOC(sizeof (OOC_CLASS_PRI_TNAME(CPORTION_MCNAME)));
    if (MNULL == pPrivate)
        goto error;
#endif    
    //............................................................................................................
    OOC_ClassCoreDef* pCore = OOC_GET_PUB_BLOCK(super, CP_SC_PKG, CP_SC_TYPE)->tLink.pCore;
    pCore->cthis = &pPubBlock->CP_MC_TYPE;
    pCore->pMetaData = &OOC_CLASS_META_VNAME(CP_MC_FNAME);
    pCore->tCtrlBlk.tFlags.bReleased = MFALSE;
    pCore->tCtrlBlk.tFlags.nRefCNT = 0;
    pCore->tCtrlBlk.finalize = (void (*)(void*))finalize;
    
    pPubBlock->tLink.pCore = pCore;
    pPubBlock->tLink.pPublic = &pPubBlock->CP_MC_TYPE;
    pPubBlock->tLink.pProtected = pProtected;
#ifdef OOC_CFG_CLASS_PORTION_USE_PRIVATE
    pPubBlock->tLink.pPrivate = pPrivate;
#else    
    pPubBlock->tLink.pPrivate = MNULL;
#endif
    
    pPubBlock->CP_MC_TYPE.CP_SC_TYPE = super;
    ((OOC_CLASS_PRO_TNAME(CP_MC_FNAME)*)pProtected)->finalize = finalize;
    CP_MC_FNAME* cthis = CPortion_default_init(&pPubBlock->CP_MC_TYPE);
    
error:
    if (MNULL == cthis) {
        OOC_CLASS_STA_VNAME_P(OBJECT_PKG, Object).release(super);
        OOC_FREE(pPubBlock);
        OOC_FREE(pProtected);
#ifdef OOC_CFG_CLASS_PORTION_USE_PRIVATE
        OOC_FREE(pPrivate);
#endif          
        return MNULL;
    }

    return cthis;

}


static void finalize(CP_MC_FNAME* cthis){
    assert(MNULL != cthis);

    Cportion_finalize(cthis);
    
    CP_SC_FNAME* super = cthis->CP_SC_TYPE;
    
    OOC_PUB_BLOCK_TNAME(CP_MC_FNAME)* pPubBlock = OOC_GET_PUB_BLOCK(cthis, CP_MC_PKG, CP_MC_TYPE);
        
    OOC_FREE(pPubBlock->tLink.pProtected);
    OOC_FREE(pPubBlock->tLink.pPrivate);
    OOC_FREE(pPubBlock);
    
    ((OOC_CLASS_PRO_TNAME(CP_SC_FNAME)*)OOC_GET_PUB_BLOCK(super, CP_SC_PKG, CP_SC_TYPE)->tLink.pProtected)->finalize(super);        
}